/* $Id: http.h,v 1.3 2006/03/15 03:49:16 jfb Exp $ */
/*
 * Copyright (c) 2003 Jean-Francois Brousseau <phrakt@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#ifndef _HTTP_MSG_H_
#define _HTTP_MSG_H_

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>

#include <limits.h>

#include <canopy/queue.h>

#include <http/uri.h>
#include <http/auth.h>
#include <http/http.h>




#define HTTP_MSG_ISLWS(c)	(((c) == ' ') || ((c) == '\t'))



/* control flags */
#define HTTP_MSG_HDR		0x01		/* format headers only */
#define HTTP_MSG_BODY		0x02		/* format body only */
#define HTTP_MSG_DYNBUF		0x04		/* dynamic buffer */

#define HTTP_MSG_FULL		(HTTP_MSG_HDR | HTTP_MSG_BODY)

enum http_msg_type {
	HTTP_MSG_REQ,
	HTTP_MSG_RESP,
};




struct http_hdr {
	char  *hdr_name;
	char  *hdr_val;
	TAILQ_ENTRY(http_hdr) hdr_link;
};



struct http_req {
	enum http_method   req_method;		/* method: GET, POST, etc. */
	char              *req_methodname;
	int                req_type;		/* simple or full ? */
	http_uri_t        *req_url;

	http_authtok_t    *req_auth;

	http_conn_t       *req_conn;
};


struct http_resp {
	int          resp_code;

	http_ent_t  *resp_ent;
};


struct http_msg {
	enum http_msg_type      msg_type;
	enum http_version       msg_version;
	time_t                  msg_crtime;	/* creation timestamp */
	TAILQ_HEAD(, http_hdr)  msg_headers;

	http_msg_t             *msg_link;

	http_ent_t             *msg_entity;

	union {
		http_req_t     mreq;
		http_resp_t    mresp;
	} msg_data;
};

#define msg_req		msg_data.mreq
#define msg_resp	msg_data.mresp



http_hdr_t*   http_hdr_create    (const char *, const char *);
void          http_hdr_free      (http_hdr_t *);
http_hdr_t*   http_hdr_parse     (const void *, size_t *);

http_msg_t*   http_msg_alloc     (enum http_msg_type);
void          http_msg_free      (http_msg_t *);
http_msg_t*   http_msg_parse     (const void *, size_t);
ssize_t       http_msg_findeol   (const void *, size_t);
ssize_t       http_msg_format    (http_msg_t *, void **, size_t *, int);
int           http_msg_sethdr    (http_msg_t *, const char *, const char *);
int           http_msg_rmhdr     (http_msg_t *, const char *);
http_hdr_t*   http_msg_gethdr    (http_msg_t *, const char *);
int           http_msg_mkenthdrs (http_msg_t *);

http_req_t*   http_req_parse   (const char *);
ssize_t       http_req_format  (http_req_t *, void **, size_t *, int);

http_resp_t*  http_resp_parse  (const char *);
ssize_t       http_resp_format (http_resp_t *, void **, size_t *, int);

#endif /* _HTTP_MSG_H_ */
